#include "place.h"

#include "transition.h"
#include "wfnet.h"

using namespace wfnet;

Place::~Place()
{

}

nid Place::getId() const
{
    return m_id;
}

QString Place::name() const
{
    return m_name;
}

const IColorSet* Place::getColorSet() const
{
    return &m_colorSet;
}

const IMultiset* Place::getTokens() const
{
    const IMultiset* multiset = 0;
    if(m_colorSet.isTimed())
    {
        multiset = &m_timedTokens;
    }
    else
    {
        multiset = &m_untimedTokens;
    }

    return multiset;
}

void Place::putTokens(IMultiset* tokens)
{
    Q_ASSERT(tokens != 0);

    const bool isTimed = m_colorSet.isTimed();

    if (isTimed && isTimed == tokens->isTimed())
    {
        TimedMultiset* tmt = dynamic_cast<TimedMultiset* >(tokens);

        Q_ASSERT(tmt != 0);

        m_timedTokens = m_timedTokens + (*tmt);
    }
    else if (!isTimed && isTimed == tokens->isTimed())
    {
        Multiset* mt = dynamic_cast<Multiset* >(tokens);

        Q_ASSERT(mt != 0);

        m_untimedTokens = m_untimedTokens + (*mt);
    }
    else
    {
        Q_ASSERT(false); // incomp. tokens
    }
}

void Place::withdrawTokens(IMultiset* tokens)
{
    const bool isTimed = m_colorSet.isTimed();

    if (isTimed && isTimed == tokens->isTimed())
    {
        TimedMultiset* tmt = dynamic_cast<TimedMultiset* >(tokens);

        Q_ASSERT(tmt != 0);

        m_timedTokens = m_timedTokens - (*tmt);
    }
    else if (!isTimed && isTimed == tokens->isTimed())
    {
        Multiset* mt = dynamic_cast<Multiset* >(tokens);

        Q_ASSERT(mt != 0);

        m_untimedTokens = m_untimedTokens - (*mt);
    }
    else
    {
        Q_ASSERT(false); // incomp. tokens
    }
}

QSet<const ITransition* > Place::getInputTransitions() const
{
    QSet<const ITransition* > iTransitions;

    if (m_node != 0)
    {
        const QSet<Node* > iConnections = m_node->getIncomingConnections();
        foreach (Node* node, iConnections)
        {
            const Transition* transition =
                dynamic_cast<const Transition *>(node->getData());

            iTransitions << transition;
        }
    }

    return iTransitions;
}

QSet<const ITransition* > Place::getOutputTransitions() const
{
    QSet<const ITransition* > oTransitions;

    if (m_node != 0)
    {
        const QSet<Node* > oConnections = m_node->getOutgoingConnections();
        foreach (Node* node, oConnections)
        {
            const Transition* transition =
                dynamic_cast<const Transition *>(node->getData());

            oTransitions << transition;
        }
    }

    return oTransitions;
}

void Place::registerNode(Node* node)
{
    m_node = node;
}

const Node* const Place::node() const
{
    return m_node;
}

Place::Place(WfNet *parent, nid id, QString name,
    IColorSet *colorSet) : QObject(parent), IPlace(), INodeData(),
        m_node(0),
        m_id(id),
        m_name(name),
        m_colorSet(*dynamic_cast<ColorSet *>(colorSet)),
        m_untimedTokens(m_colorSet.name()),
        m_timedTokens(m_colorSet.name())
{

}

void Place::clearTokens()
{
    m_untimedTokens.clear();
    m_timedTokens.clear();
}
